//
//  SLDBAccess.m
//  SLAdingo
//
//  Created by 徐 廷 on 10/04/01.
//  Copyright 2010 adingo Inc. All rights reserved.
//

#import "SLDBAccess.h"
#import "SLApp.h"
#import "SynthesizeSingleton.h"
#import "SLTrace.h"

@implementation SLDBAccess

@synthesize database, connected;

SYNTHESIZE_SINGLETON_FOR_CLASS(SLDBAccess);

- (OSStatus) initImmutableDBWith: (NSString*) DBFileName{
    if (nil == DBFileName || [DBFileName isEqualToString:@""]) {
        return fileNotExist;
    }
    
    if (self.connected) {
        return noErr;
    }
    
    // 1. file exist?
    NSFileManager *fileManager = [NSFileManager defaultManager];

    NSString *DBFullPath = [[SLApp getBundleDirectory] stringByAppendingPathComponent:DBFileName];
    
    if(![fileManager fileExistsAtPath:DBFullPath]) {
        dbPath = nil;
        return fileNotExist;
    }
    
    // 2. record file path;
    dbPath = DBFullPath;
    
    return [self connectDB];
}

- (OSStatus) initMutableDBWith: (NSString*) DBFileName{
    if (nil == DBFileName || [DBFileName isEqualToString:@""]) {
        return fileNotExist;
    }
    
    // 1. file exist?
    NSFileManager *fileManager = [NSFileManager defaultManager];
    
    NSString *docDBFullPath = [[SLApp getDocumentFolder] stringByAppendingPathComponent:DBFileName];
    
    if(![fileManager fileExistsAtPath:docDBFullPath]) {
        NSString *bundleDBFullPath = [[SLApp getBundleDirectory] stringByAppendingPathComponent:DBFileName];
        if (![fileManager fileExistsAtPath:bundleDBFullPath]) {
            // The DB is even not exist in bundle directory. The file name must be wrong.
            dbPath = nil;
            return fileNotExist;
        }else {
            // Copy to directoryFolder
            NSError *err;
            BOOL success = [fileManager copyItemAtPath:bundleDBFullPath toPath:docDBFullPath error:&err];
            if (!success) {
                NSLog(@"Error: [%@]=[%@]", [err code], [err description]);
                return copyFailed;
            }
        }

    }
    
    // 2. record file path;
    dbPath = docDBFullPath;
    
    return [self connectDB];
}


- (OSStatus) connectDB{
    if (!dbPath){
        // file not exist.
        return fileNotExist;
    }
    
    if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {
        connected = YES;
        return noErr;
    }else {
        [self closeDB];
        return openFailed;
    }
    
    return noErr;
}

- (OSStatus) closeDB{
    if (connected && database == NULL) {
        return noErr;
    }
    
    if (sqlite3_close(database) != SQLITE_OK){
        SLLog(@"Failed to close database with message '%s'.", sqlite3_errmsg(database));
        return closeFailed;
    }
    
    dbPath = nil;
    database = NULL;
    connected = NO;
    return noErr;
}

#pragma mark -
#pragma mark DB Common
+ (NSString *) getSafeNSStringFromCString:(const void *)buffer{
	const void *value = buffer;
	if (value != nil){
		return [NSString stringWithUTF8String:(const char *)value];
	}else {
		return nil;
	}
    
}

+ (NSData *) getSafeDataFrom:(const void *)bytes length:(NSUInteger)length{
	if (bytes != nil){
		return [[NSData alloc] initWithBytes:bytes length:length];
	}else {
		return nil;
	}
	
}

@end
